package com.truing.flycodebill.workbench.web.controller;


import com.truing.flycodebill.commons.constant.Constant;
import com.truing.flycodebill.commons.domain.ReturnObject;
import com.truing.flycodebill.commons.utils.DateUtils;
import com.truing.flycodebill.commons.utils.UUIDUtil;
import com.truing.flycodebill.settings.domain.User;
import com.truing.flycodebill.workbench.domain.Bill;
import com.truing.flycodebill.workbench.service.BillService;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.OutputStream;
import java.util.*;

@Controller
@CrossOrigin
public class BillController {

    @Resource
    private BillService billService;


    /**
     * 保存创建的账单记录
     *  方法需要实现：
     *      1、把来自前台的新增的账单记录的数据以及owner，id，创建时间字段封装成到Bill对象里
     *      2、调用BillService，在数据库中插入新增的账单记录。
     *      3、根据Service返回值封装returnObject返回给前端。
     * @param bill
     * @param session
     * @return
     */
    @RequestMapping("/saveCreateBill.do")
    @ResponseBody
    public Object saveCreateBill(Bill bill, HttpSession session){
        User user = (User) session.getAttribute(Constant.SESSION_USER);
        //封装参数
        bill.setId(UUIDUtil.getUUID());
        bill.setCreateTime(DateUtils.formatDate(new Date()));
        bill.setOwner(user.getId());
        ReturnObject returnObject = new ReturnObject();
        try {
            //调用service层方法，保存创建的账单
            int ret = billService.saveCreateBill(bill);
            if (ret > 0){
                returnObject.setCode(Constant.RETURN_OBJECT_CODE_SUCCESS);
            }else {
                returnObject.setCode(Constant.RETURN_OBJECT_CODE_FAIL);
                returnObject.setMessage("系统忙，请稍后重试......");
            }
        }catch (Exception e){
            e.printStackTrace();
            returnObject.setCode(Constant.RETURN_OBJECT_CODE_FAIL);
            returnObject.setMessage("系统忙，请稍后重试......");
        }
        return returnObject;
    }

    /**
     * 分页查询账单记录
     *  方法需要实现：
     *      1、把前台接收的账单记录和分页数据封装到Map中
     *      2、调用billService中的方法，查询账单记录，返回记录List
     *      3、将账单List和总记录条数totalRows封装到一个retMap中
     *      4、把retMap返回给前台
     * @param title
     * @param startDate
     * @param endDate
     * @param type
     * @return
     */
    @RequestMapping("/queryBillByConditionForPage.do")
    @ResponseBody
    public Object queryBillByConditionForPage(HttpSession session,String title, String startDate, String endDate, String type){

        User user = (User)session.getAttribute(Constant.SESSION_USER);

        //收集参数：我们根据service层方法需要的参数--->map
        Map<String,Object> map = new HashMap<>();
        //把参数封装进map
        map.put("owner",user.getId());
        map.put("title",title);
        map.put("type",type);
        map.put("startDate",startDate);
        map.put("endDate",endDate);
        //查询符合条件的账单,返回一个Bill实体类组成的List
        //封装返回值
        List<Bill> billList = billService.selectBillByConditionForPage(map);
        Map<String,Object> map1 = new HashMap<>();
        map1.put("billList",billList);
        return map1;
    }

    /**
     * 根据账单的id删除账单记录
     *  方法需要实现的功能：
     *      1、调用BillService方法，删除账单
     *      2、根据响应信息， ReturnObject
     * @param id
     * @return
     */
    @RequestMapping("/deleteBillByIds.do")
    @ResponseBody
    public Object deleteBillByIds(String[] id){
        ReturnObject returnObject = new ReturnObject();
        try {
            //调用service删除账单
            int ret = billService.deleteBillByIds(id);
            //根据处理结果删除响应信息
            if (ret>0){
                returnObject.setCode(Constant.RETURN_OBJECT_CODE_SUCCESS);
                returnObject.setMessage("删除成功");
            }else {
                returnObject.setCode(Constant.RETURN_OBJECT_CODE_FAIL);
                returnObject.setMessage("系统忙，请稍后重试....");
            }
        }catch (Exception e){
            e.printStackTrace();
            returnObject.setCode(Constant.RETURN_OBJECT_CODE_FAIL);
            returnObject.setMessage("系统忙，请稍后重试....");
        }
        return returnObject;
    }

    /**
     * 根据id查询账单信息
     *   方法需要实现的功能：
     *      1、调用BillService方法，查询id对应的账单
     *      2、以json返回账单实体类
     *
     * @param id
     * @return
     */
    @RequestMapping("/queryBillById.do")
    @ResponseBody
    public Object queryBillById(String id){
        //调用service查询账单
        Bill bill= billService.queryBillById(id);
        //根据查询结果，返回响应信息
        return bill;
    }

    /**
     *  保存修改的账单记录
     *    方法需要实现：
     *       1、把来自前台的修改的账单记录的数据以及owner，创建时间字段封装成到Bill对象里
     *       2、调用BillService，在数据库中修改的账单记录。
     *       3、根据Service返回值封装returnObject返回给前端。
     * @param bill
     * @return
     */
    @RequestMapping("/saveEditBill.do")
    @ResponseBody
    public Object saveEditBill(Bill bill){
        bill.setCreateTime(DateUtils.formatDate(new Date()));
        ReturnObject returnObject = new ReturnObject();
        try{
            //调用service层方法，保存修改的账单
            int ret = billService.saveEditBill(bill);
            if (ret > 0){
                returnObject.setCode(Constant.RETURN_OBJECT_CODE_SUCCESS);
                returnObject.setMessage("保存成功");
            }else {
                returnObject.setCode(Constant.RETURN_OBJECT_CODE_FAIL);
                returnObject.setMessage("系统忙，请稍后....");
            }
        }catch (Exception e){
            e.printStackTrace();
            returnObject.setCode(Constant.RETURN_OBJECT_CODE_FAIL);
            returnObject.setMessage("系统忙，请稍后....");
        }
        return returnObject;
    }

    @RequestMapping("/exportAllBills.do")
    public void exportAllBills(HttpSession session,HttpServletResponse response)throws Exception{
        User user = (User)session.getAttribute(Constant.SESSION_USER);
        List<Bill> billList = billService.queryBillByOwnerId(user.getId());
        //创建excel文件，把billList写入到excel文件中
        //根据查询结果，生成响应信息(创建excel文件，并且把List写入到excel文件中)
        //创建excel文件
        HSSFWorkbook wb = new HSSFWorkbook();
        HSSFSheet sheet = wb.createSheet("账单信息列表");
        HSSFRow row = sheet.createRow(0);
        HSSFCell cell = row.createCell(0);
        cell.setCellValue("ID");
        cell = row.createCell(1);
        cell.setCellValue("账单标题");
        cell = row.createCell(2);
        cell.setCellValue("账单时间");
        cell = row.createCell(3);
        cell.setCellValue("账单分类");
        cell = row.createCell(4);
        cell.setCellValue("账单类型");
        cell = row.createCell(5);
        cell.setCellValue("账单金额");
        cell = row.createCell(6);
        cell.setCellValue("备注");
        cell = row.createCell(7);
        cell.setCellValue("创建时间");
        //遍历List，创建HSSFRow对象，生成所有数据的行
        if (billList!=null && billList.size()>0){
            Bill bill= null;
            for (int i = 0;i<billList.size();i++){
                bill=billList.get(i);
                //每遍历出一行activity，生成一行
                row = sheet.createRow(i+1);
                cell = row.createCell(0);
                cell.setCellValue(bill.getId());
                cell = row.createCell(1);
                cell.setCellValue(bill.getTitle());
                cell = row.createCell(2);
                cell.setCellValue(bill.getBillTime());
                cell = row.createCell(3);
                cell.setCellValue(bill.getSort());
                cell = row.createCell(4);
                cell.setCellValue(bill.getType());
                cell = row.createCell(5);
                cell.setCellValue(bill.getPrice());
                cell = row.createCell(6);
                cell.setCellValue(bill.getRemark());
                cell = row.createCell(7);
                cell.setCellValue(bill.getCreateTime());
            }
        }
        //把生成的excel文件下载到客服端
        response.setContentType("application/octet-stream;charset=UTF-8");
        OutputStream out = response.getOutputStream();
        response.addHeader("Content-Disposition","attachment;filename=BillList.xls");
        //关闭资源
        wb.write(out);
        wb.close();
        out.flush();
    }
    /**
     * 生成账单简报
     */
    @RequestMapping("/generateBillBrief.do")
    @ResponseBody
    public Object generateBillBrief(HttpSession session){
        User user = (User)session.getAttribute(Constant.SESSION_USER);
        String typeIdOfExpend = "1";
        String typeIdOfIncoming = "2";
        ReturnObject returnObject = new ReturnObject();
        try{
            int countOfBills = billService.queryCountOfBills();
            if (countOfBills == 0){
                returnObject.setCode(Constant.RETURN_OBJECT_CODE_SUCCESS);
                returnObject.setMessage(user.getName()+"您好，欢迎使用飞码记账，赶紧完成您的第一笔记账吧");
            }else {
                int countOfExpendBills = billService.queryCountOfBillsByTypeId(typeIdOfExpend);
                int countOfIncomingBills = billService.queryCountOfBillsByTypeId(typeIdOfIncoming);
                returnObject.setCode(Constant.RETURN_OBJECT_CODE_SUCCESS);
                returnObject.setMessage(user.getName()+"您好，欢迎使用飞码记账，您当前一共记账"+
                        countOfBills+"笔，其中支出"+countOfExpendBills+"笔，收入"+countOfIncomingBills+"笔。");
            }
        }catch (Exception e){
            e.printStackTrace();
            returnObject.setCode(Constant.RETURN_OBJECT_CODE_FAIL);
            returnObject.setMessage("系统忙，请稍后....");
        }
        return returnObject;
    }
    @RequestMapping("showTopFiveBills.do")
    @ResponseBody
    public Object showTopFiveBills(){
        List<Bill> billList = billService.queryTopFiveBills();
        Map<String,Object> map = new HashMap<>();
        map.put("billList",billList);
        return map;
    }

    @RequestMapping("showBillsByTitle.do")
    @ResponseBody
    public Object showBillsByTitle(String title){
       return null;
    }

    /**
     * 展示账单图表
     */
    @RequestMapping("/showBillCharts.do")
    @ResponseBody
    public Object showBillCharts(String type,String startDate,String endDate){

        Map<String,Object> map = new HashMap<>();
        //把参数封装进map
        map.put("type",type);
        map.put("startDate",startDate);
        map.put("endDate",endDate);

        ReturnObject returnObject = new ReturnObject();
        try{
            //调用service层方法，保存修改的账单
            List<Bill> billList = billService.queryBillByBillTimeAndType(map);
            if (billList !=null && billList.size()>0){
                List<String> dateList = new ArrayList<>();
                List<Integer> priceList = new ArrayList<>();
                Bill bill = null;
                for (int i = 0; i<billList.size();i++){
                    bill = billList.get(i);
                    if (i == 0){

                        dateList.add(bill.getBillTime().substring(5));
                        priceList.add(Integer.parseInt(bill.getPrice()));
                    }else {
                        if (!(bill.getBillTime().substring(5)).equals(billList.get(i-1).getBillTime().substring(5))){
                            dateList.add(bill.getBillTime().substring(5));
                            priceList.add(Integer.parseInt(bill.getPrice()));
                        }else {
                            int temp = priceList.get(priceList.size()-1);
                            priceList.remove(priceList.size()-1);
                            priceList.add(Integer.parseInt(bill.getPrice())+temp);
                        }
                    }
                }
                Map<String,Object> map1 = new HashMap<>();
                map1.put("dateList",dateList);
                map1.put("priceList",priceList);
                returnObject.setCode(Constant.RETURN_OBJECT_CODE_SUCCESS);
                returnObject.setReturnData(billList);
                returnObject.setReturnData(map1);
            }else {
                returnObject.setCode(Constant.RETURN_OBJECT_CODE_FAIL);
                returnObject.setMessage("系统忙，请稍后....");
            }
        }catch (Exception e){
            e.printStackTrace();
            returnObject.setCode(Constant.RETURN_OBJECT_CODE_FAIL);
            returnObject.setMessage("系统忙，请稍后....");
        }
        return returnObject;
    }
}
